package br.edu.unifei.cct720.alieninvasion.entity.alien;

import br.edu.unifei.cct720.alieninvasion.entity.Entity;
import br.edu.unifei.cct720.alieninvasion.entity.ship.ShipShotEntity;
import br.edu.unifei.cct720.alieninvasion.main.gui.GameCanvas;
import br.edu.unifei.cct720.alieninvasion.resources.SoundEffect;
import br.edu.unifei.cct720.alieninvasion.resources.Sprite;
import br.edu.unifei.cct720.alieninvasion.resources.SpriteStore;
import br.edu.unifei.cct720.alieninvasion.utils.Constants;

/**
 * Class to represent an entity of an alien
 * 
 * @author Felipe Knappe
 *
 */
public class AlienEntity extends Entity {

	/**
	 * The speed at which the entity moves
	 */
	private double moveSpeed = 75;

	/**
	 * The animation frames
	 */
	private Sprite[] frames;

	/**
	 * The time since the last frame change took place
	 */
	private long lastFrameChange;

	/**
	 * The frame duration in milliseconds, i.e. how long any given frame of animation lasts
	 */
	private long frameDuration = 250;

	/**
	 * The current frame of animation being displayed
	 */
	private int frameNumber;

	/**
	 * True if entity moves to the right side of the screen
	 */
	private boolean directToRight = true;

	/**
	 * Class Constructor
	 * Create a new alien entity
	 * 
	 * @param game The game in which this entity is being created
	 * @param x The intial x-coordinate of this entity
	 * @param y The intial y-coordinate of this entity
	 */
	public AlienEntity(GameCanvas game, int x, int y, int nFrames) {
		super(game, Constants.ALIEN_MOVE_LEFT, x, y + 75);

		this.dx = -moveSpeed;

		// setup the animation frames
		this.frames = new Sprite[nFrames];
		for(int i = 0; i < nFrames; i++) {
			this.frames[i] = SpriteStore.get().getSprite(Constants.ALIEN_MOVE_LEFT);
		}
	}

	/**
	 * Method responsible for request that this entity move
	 * itself based on time elapsed.
	 * 
	 * @param delta The shift value
	 * 
	 */
	public void move(long delta) {
		
		/*
		 * Since the shift value tell how much time has passed,
		 * it is used to drive the frame animation
		 */
		lastFrameChange += delta;

		/*
		 * If a frame change is needed, 
		 * then do an update on the frame number
		 * and flip over the sprite in use
		 */
		if (lastFrameChange > frameDuration) {
			// reset our frame change time counter
			lastFrameChange = 0;

			// update the frame
			frameNumber++;
			if (frameNumber >= frames.length) {
				frameNumber = 0;
			}

			// loop to animate the sprites (look to the left or to the right)
			sprite = frames[frameNumber];
			for(int i = 0; i < frames.length; i++) {
				if(directToRight) {
					directToRight = false;	
					frames[i] = SpriteStore.get().getSprite(Constants.ALIEN_MOVE_LEFT);
				} else {
					directToRight = true;	
					frames[i] = SpriteStore.get().getSprite(Constants.ALIEN_MOVE_RIGHT);
				}
			}
		}

		/* 
		 * If the entity reached the left hand side of the screen and
		 * are moving left then request a logic update
		 */
		if ((dx < 0) && (x < 10)) {
			game.updateLogic();
		}
		
		/*
		 * Otherwise, if reached the right hand side of the screen
		 * and are moving to rightm then request a logic update 
		 */
		if ((dx > 0) && (x > 750)) {
			game.updateLogic();
		}

		// proceed with normal move
		super.move(delta);
	}

	/**
	 * Method responsible to update the 
	 * game logic related to aliens.
	 * 
	 */
	public void doLogic() {
		/*
		 * Swap over horizontal movement and move down the
		 * screen a bit
		 */
		dx = -dx;
		y += 25;

		/*
		 * if the entity has reached the bottom of the screen,
		 * then the player dies
		 */
		if (y > 570) {
			game.notifyDeath();
		}
	}

	/**
	 * Method responsible for notify this entity that it has collided 
	 * with another entity.
	 * 
	 * @param other The other collided entity
	 * 
	 */
	@Override
	public void collidedWith(Entity other) {
		// if collision occurred with a shot entity, it dies
		if(other instanceof ShipShotEntity) {
			game.notifyEnemyKilled();
			game.removeAlienEntity(this);
		}
	}
}